flock関数は、ファイルに対してロックの適用・解除を行います。ロックには、次の2種類があります。
- 共有ロック
- 他のプロセスからファイルを参照することはできますが、変更はできません。
- 排他ロック
- 他のプロセスからファイルの参照も変更もできません。
この関数は、C言語のライブラリ関数(標準関数)ではありませんので、コンパイラにより、使えない場合があります。
#include <sys/file.h>
int flock(int fd, int operation);
fdはopen関数又は、creat関数でファイルをオープンした時に取得した、ファイル・ディスクリプタを指定します。
operationはロックの種類を指定します。
戻り値として、処理が成功した場合は0が、エラーの場合は-1を返します。
第2引数のoperationには、次の値を指定できます。
| 値 | 意味 |
|---|---|
| LOCK_SH | 共有ロックを適用します。 |
| LOCK_EX | 排他ロックを適用します。 |
| LOCK_UN | ロックを解除します。 |
ロックを適用した複数のプロセスがファイルにアクセスすると、1つのプロセスのみがアクセスできて、その他のプロセスは停止(block)します。非停止(non-blocking)タイプの要求を行うには、上記の操作(operation)にLOCK_NBを論理和(OR)の形で指定します。また、1つのファイルに対して、共有ロックと排他ロックを同時に設定することはできません。
ロックの解除は第2引数のoperationにLOCK_UNを指定して実行するか、ファイルをクローズした場合に行われます。
プログラム 例
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/file.h>
int main(int argc, char **argv)
{
char pathname[] = './temp_lock.txt';
int fd;
char out_buff[100];
int outcnt;
int return_code = 0;
/* 書き込み専用、追加モードでオープン */
if ((fd = open(pathname, O_WRONLY | O_APPEND)) != -1) {
/* 排他ロックをかける */
if (flock(fd, LOCK_EX) == 0) {
/* メッセージ出力 */
for (outcnt = 1; outcnt <= 3; ++outcnt) {
sprintf(out_buff, '%s : %d回目\n', *(argv + 1), outcnt);
write(fd, out_buff, strlen(out_buff));
sleep(2);
}
/* ロック解除 */
flock(fd, LOCK_UN);
}
else {
perror('');
return_code = 2;
}
close(fd);
}
else {
perror('');
return_code = 1;
}
return return_code;
}
例の実行結果
flock.exe実行コマンドで、&記号を付けて並列実行を行っています。
$ cat temp_lock.txt This is temp_lock.txt. $ $ ./flock.exe Proc01 & [1] 2796 $ ./flock.exe Proc02 & [2] 2797 $ ./flock.exe Proc03 & [3] 2798 [1] Done ./flock.exe Proc01 $ ./flock.exe Proc04 & [4] 2799 [2] Done ./flock.exe Proc02 $ [3]- Done ./flock.exe Proc03 [4]+ Done ./flock.exe Proc04 $ cat temp_lock.txt This is temp_lock.txt. Proc01 : 1回目 Proc01 : 2回目 Proc01 : 3回目 Proc02 : 1回目 Proc02 : 2回目 Proc02 : 3回目 Proc03 : 1回目 Proc03 : 2回目 Proc03 : 3回目 Proc04 : 1回目 Proc04 : 2回目 Proc04 : 3回目 $